package com.cmsz.collection.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 日期、时间类
 * 
 * @author cmt
 *
 */
public class DateUtil {

	/**
	 * 日期转换
	 * 
	 * @author cmt
	 * @param time
	 * @param fmt:yyyy-MM-dd
	 *            HH:mm:ss
	 * @return
	 */
	public static String formatTime(Timestamp time, String fmt) {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(fmt);
		LocalDateTime localDateTime = time.toLocalDateTime();
		return dateTimeFormatter.format(localDateTime);
	}

	/**
	 * 获取系统当前时间（毫秒为0）
	 * 
	 * @author cmt
	 * @return
	 */
	public static Timestamp getTime() {
		LocalDateTime localDateTime = LocalDateTime.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		return Timestamp.valueOf(localDateTime.format(dateTimeFormatter));
	}
	
	/**
	 * 获取系统当前时间（包括准确的毫秒）
	 * 
	 * @author cmt
	 * @return
	 */
	public static Timestamp getTime2() {
		Instant instant =Instant.now();
		return Timestamp.from(instant);
	}
	
	/**
	 * yyyy-MM-dd HH:mm:ss 转换成Timestamp
	 * @Description: yyyy-MM-dd HH:mm:ss 转换成Timestamp
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午2:40:41
	 * @param timeString
	 * @return
	 */
	public static Timestamp getTime(String timeString) {
		return Timestamp.valueOf(timeString);
	}

	/**
	 * 
	 * @Description: 获取当前日期的0时0分0秒0毫秒
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午2:35:06
	 * @return
	 */
	public static Timestamp getDateFirst() {
		LocalDate localDate = LocalDate.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
		return Timestamp.valueOf(dateTimeFormatter.format(localDate));
	}

	/**
	 * 获取当前日期(时间23:59:59)
	 * 
	 * @author cmt
	 * @return
	 */
	public static Timestamp getDateLast() {
		LocalDate localDate = LocalDate.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
		return Timestamp.valueOf(dateTimeFormatter.format(localDate));
	}

	/**
	 * 取得当前日期,格式yyyyMMdd
	 * @Description: 取得当前日期,格式yyyyMMdd
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午2:39:28
	 * @return
	 */
	public static String getCurrDate() {
		LocalDate localDate = LocalDate.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
		return dateTimeFormatter.format(localDate);
	}


	/**
	 * 格式化日期
	 * @Description: 格式化日期
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午2:49:58
	 * @param date
	 * @param fmt
	 * @return
	 */
	public static String formatDate(Date date, String fmt) {

		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(fmt);
		LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
		return dateTimeFormatter.format(localDateTime);
	}
	
	/**
	 * 获取本周 周一时间，返回 格式yyyy-MM-dd 00:00:00.0
	 * @Description: 获取本周 周一时间，返回 格式yyyy-MM-dd 00:00:00.0
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午3:21:57
	 * @return
	 */
	public static Timestamp getMonday() {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
		LocalDateTime localDateTime = LocalDateTime.now();
		LocalDateTime mondayLastWeek = localDateTime.with(DayOfWeek.MONDAY).with(LocalTime.MIN);
		return Timestamp.valueOf(dateTimeFormatter.format(mondayLastWeek));
	}


	/**
	 * 获取本周 周日时间，返回 格式yyyy-MM-dd 23:59:59.0
	 * @Description: 获取本周 周日时间，返回 格式yyyy-MM-dd 23:59:59.0
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午3:21:39
	 * @return
	 */
	public static Timestamp getSunday() {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
		LocalDateTime localDateTime = LocalDateTime.now();
		LocalDateTime sundayLastWeek = localDateTime.with(DayOfWeek.SUNDAY).with(LocalTime.MIN);
		return Timestamp.valueOf(dateTimeFormatter.format(sundayLastWeek));
	}

	/**
	 * 增加天数
	 * @Description: 增加天数
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午3:24:23
	 * @param time
	 * @param day
	 * @return
	 */
	public static Timestamp addDay(Timestamp time, Integer day) {

		LocalDateTime localDateTime1 = LocalDateTime.ofInstant(time.toInstant(), ZoneId.systemDefault());
		return Timestamp.valueOf(localDateTime1.plusDays(day));
	}

	/**
	 *  2个时间点的相差天数
	 * @Description:2个时间点的相差天数
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午3:41:13
	 * @param time1
	 * @param time2
	 * @return
	 */
	public static long getDay(Timestamp time1, Timestamp time2) {
		LocalDateTime localDateTime1 = time1.toLocalDateTime();
		LocalDateTime localDateTime2 = time2.toLocalDateTime();
		LocalDate localDate1 = localDateTime1.toLocalDate();
		LocalDate localDate2 = localDateTime2.toLocalDate();
		
		return localDate1.toEpochDay() - localDate2.toEpochDay();
	}

	/**
	 * 两个日期相距多少天 
	 * 
	 * @param oldDate 格式 yyyyMMdd
	 * @param newDate 格式 yyyyMMdd
	 * @return 相距的天数
	 * @throws ParseException
	 */
	public static long getsubDate(String oldDate, String newDate) throws ParseException {

		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
		LocalDate localDate1 = LocalDate.parse(oldDate, dateTimeFormatter);
		LocalDate localDate2 = LocalDate.parse(newDate, dateTimeFormatter);

		return localDate2.toEpochDay() - localDate1.toEpochDay();
	}

	/**
	 * 两个日期相减 格式 yyyyMMdd
	 * 
	 * @param oldDate
	 * @param newDate
	 * @return 相差的天数
	 */
	public static long getsubDate(Date oldDate, Date newDate) {
		LocalDate localDate1 = oldDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		LocalDate localDate2 = newDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		return localDate2.toEpochDay() - localDate1.toEpochDay();
	}


	/**
	 * 转换成时间 字符串格式
	 * 
	 * @author yangquan
	 * @return Date
	 * @throws ParseException
	 */

	/**
	 * 
	 * @Description: 转换成功date
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午4:48:42
	 * @param format 格式
	 * @return
	 * @throws ParseException
	 */
	public static Date parseToDate(String srcdateStr, String format) throws ParseException {

		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
		LocalDateTime localDateTime = LocalDateTime.parse(srcdateStr, dateTimeFormatter);
		return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

	}

	/**
	 * 获取上月的第一天yyyy-MM-dd 00:00:00和最后一天yyyy-MM-dd 23:59:59
	 * @Description: 获取上月的第一天yyyy-MM-dd 00:00:00和最后一天yyyy-MM-dd 23:59:59
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午4:34:46
	 * @return
	 */
	public static Map<String, String> getPreMonth() {
		
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
		DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");

		LocalDateTime today = LocalDateTime.now();
		// 上个月今天
		LocalDateTime prevMonthtoday = today.plusMonths(-1);
		// 上个月的第一天
		LocalDateTime prevMonthFD = prevMonthtoday.with(TemporalAdjusters.firstDayOfMonth());
		// 上个月的最后一天
		LocalDateTime prevMonthPD = prevMonthtoday.with(TemporalAdjusters.lastDayOfMonth());

		Map<String, String> map = new HashMap<String, String>(2);
		map.put("prevMonthFD", prevMonthFD.format(formatter));
		map.put("prevMonthPD", prevMonthPD.format(formatter1));
		return map;
	}

	
	/**
	 * 获取上周 周一时间，返回 格式yyyy-MM-dd 00:00:00
	 * @Description: 获取上周 周一时间，返回 格式yyyy-MM-dd 00:00:00
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午4:50:42
	 * @return
	 */
	public static Timestamp getPreMonday() {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
		LocalDateTime today = LocalDateTime.now();
		// 上周的今天
		LocalDateTime sameDayLastWeek = today.minusWeeks(1);
		// 上周的周一
		LocalDateTime mondayLastWeek = sameDayLastWeek.with(DayOfWeek.MONDAY).with(LocalTime.MIN);
		// 上周的周日
		//LocalDateTime sundayLastWeek = sameDayLastWeek.with(DayOfWeek.SUNDAY);

		return Timestamp.valueOf(mondayLastWeek.format(dateTimeFormatter));
	}

	/**
	 * 获取上周 周日时间，返回 格式yyyy-MM-dd 23:59:59
	 * @Description: 获取上周 周日时间，返回 格式yyyy-MM-dd 23:59:59
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午4:50:57
	 * @return
	 */
	public static Timestamp getPreSunday() {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
		LocalDateTime today = LocalDateTime.now();
		// 上周的今天
		LocalDateTime sameDayLastWeek = today.minusWeeks(1);
		// 上周的周一
		//LocalDateTime mondayLastWeek = sameDayLastWeek.with(DayOfWeek.MONDAY);
		// 上周的周日
		LocalDateTime sundayLastWeek = sameDayLastWeek.with(DayOfWeek.SUNDAY).with(LocalTime.MAX);

		return Timestamp.valueOf(sundayLastWeek.format(dateTimeFormatter));
	}

	/**
	 * 
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午4:59:04
	 * @return
	 */
	public static String getDateyyyyMMddHHmmssSSSStr() {
		
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
		LocalDateTime localDateTime = LocalDateTime.now();
		return localDateTime.format(dateTimeFormatter);

	}
	
	/**
	 * 
	 * @Description:  获取系统当前时间（yyyyMMddHHmm格式）
	 * @author yaoQingCan
	 * @date 2018年1月22日 下午4:24:33
	 * @return
	 */
	public static String getDateyyyyMMddHHmm() {
		LocalDateTime localDateTime = LocalDateTime.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmm");
		return dateTimeFormatter.format(localDateTime);
	}

	public static Date getDateyyyyMMddHHmmssSSS() throws ParseException {
		
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
		LocalDateTime localDateTime = LocalDateTime.now();
		String landing = localDateTime.format(dateTimeFormatter);
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return Date.from(instant);
	}

	public static String getDateyyyyMMddHHmmss() {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
		LocalDateTime localDateTime = LocalDateTime.now();
		return localDateTime.format(dateTimeFormatter);
	}

	public static String getDateyyyyMMdd() {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
		LocalDateTime localDateTime = LocalDateTime.now();
		return localDateTime.format(dateTimeFormatter);
	}

	/**
	 * 获取t天前日期，格式yyyyMM
	 * 
	 * @return
	 */
	public static String getDateyyyyMMdd(int t) {
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
		LocalDateTime localDateTime = LocalDateTime.now();
		localDateTime = localDateTime.plusDays(-t);

		return localDateTime.format(dateTimeFormatter);
	}

	/**
	 * 获取当前月份，格式yyyyMM
	 * 
	 * @return
	 */
	public static String getMonth() {
		LocalDateTime localDateTime = LocalDateTime.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM");
		return localDateTime.format(dateTimeFormatter);
	}

	/**
	 * 取当前时间，精确到秒， 格式为 yyyy-MM-dd HH:mm:ss
	 * 
	 * @return
	 */
	public static String getCurrentDateTime() {
		LocalDateTime localDateTime = LocalDateTime.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		return localDateTime.format(dateTimeFormatter);
	}

	/**
	 * 取当前时间精确到毫秒 ，格式为 yyyy-MM-dd HH:mm:ss:SSS
	 * 
	 * @return
	 */
	public static String getCurrentDateTimeMS() {
		LocalDateTime localDateTime = LocalDateTime.now();
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS");
		return localDateTime.format(dateTimeFormatter);
	}

	/**
	 * 获取昨天天日期（T日） 格式为yyyyMMdd
	 * 
	 * @author: louiszhang
	 * @throws Exception
	 * @date: 2015-11-26下午3:07:23
	 */
	public static String getYesterday() {

		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
		LocalDateTime localDateTime = LocalDateTime.now();
		localDateTime = localDateTime.plusDays(-1);

		String landing = localDateTime.format(dateTimeFormatter);
		return landing;
	}

	/**
	 * 获取某个具体的日期所在月的最早时刻（具体日期所在月的第一天0时0分0秒0毫秒）
	 * 
	 * @param dateSource
	 *            某个具体日期
	 * @param
	 * @return 具体日期所在月的第一天0时0分0秒0毫秒
	 * @throws ParseException
	 */
	public static String getFirstDayOfMonth(String dateSource, String dateSourcePattern, String outPattern)
			throws ParseException {
		
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateSourcePattern);
		LocalDateTime localDateTime = LocalDateTime.parse(dateSource, dateTimeFormatter);
		LocalDateTime firstOfDay = localDateTime.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
		DateTimeFormatter dateTimeFormatterOut = DateTimeFormatter.ofPattern(outPattern);
		return dateTimeFormatterOut.format(firstOfDay);
	}

	/**
	 * 获取具体日期所在月的最后一天（具体日期所在月的最后一天23时59分59秒999毫秒）
	 * 
	 * @param dateSource
	 *            某个具体日期
	 * @param dateSourcePattern
	 *            日期格式
	 * @param outPattern
	 *            方法返回的日期格式
	 * @return 具体日期所在月的最后一天23时59分59秒999毫秒
	 * @throws ParseException
	 */
	public static String getLastDayOfMonth(String dateSource, String dateSourcePattern, String outPattern)
			throws ParseException {

		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateSourcePattern);
		LocalDateTime localDateTime = LocalDateTime.parse(dateSource, dateTimeFormatter);
		LocalDateTime endOfDay = localDateTime.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
		DateTimeFormatter dateTimeFormatterOut = DateTimeFormatter.ofPattern(outPattern);
		return dateTimeFormatterOut.format(endOfDay);
	}

	/**
	 * 根据所需要的时间格式，获取系统当前时间的字符串表示形式
	 * 
	 * @param pattern
	 *            时间格式
	 * @return 当前系统时间的字符串表示形式
	 */

	public static String getCurrentTimeDescByPattern(String pattern) {
		
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
		LocalDateTime arriveDate = LocalDateTime.now();
		return arriveDate.format(dateTimeFormatter);

	}


	/**
	 * 将指定月份减去几个月 （如：获取上个月）
	 * @param monthStr
	 * @param pattern
	 * @param minusMonth
	 * @return yyyyMM
	 */
	public static String minusYearMonth(String monthStr, String pattern, int minusMonth) {
		// 将指定格式(yyyyMM)的字符串 转为 YearMonth
		YearMonth yearMonth = YearMonth.parse(monthStr, DateTimeFormatter.ofPattern(pattern));
		// 减去指定月份
		YearMonth settleYearMonth = yearMonth.minusMonths(minusMonth);
		// yyyy-MM 转 yyyyMM
		return settleYearMonth.toString().replace("-", "");
	}

	/**
	 * 将UTC时间格式转换成yyyyMMddHHmm时间格式
	 * @param time	utc时间
	 * @return	yyyyMMddHHmm时间
	 */
	public static String UTCTimeToyyyyMMddHHmm(String time){
		// utc时间格式
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
		// 转换之后的时间格式
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmm");
		try{
			Date parse = sdf1.parse(time);
			return sdf2.format(parse);
		}catch (Exception e){
			return null;
		}
	}

	/**
	 * 将UTC格式的字符串转换为日期格式
	 * @param time	UTC格式字符串
	 * @return	时间类型
	 */
	public static Date UTCTimeToLocalDate(String time){
		// utc时间格式
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
		try {
			return sdf1.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String UTCTimeToCurrentDateTime(String time){
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try{
			Date parse = sdf1.parse(time);
			return sdf2.format(parse);
		}catch (ParseException e){
			e.printStackTrace();;
			return null;
		}
	}

	/**
	 * 获取UTC格式时间
	 * @return	UTC格式时间
	 */
	public static String getUTCTime(){
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String time = DateUtil.getDateyyyyMMddHHmmssSSSStr();
		try {
			Date date = sdf2.parse(time);
			return sdf1.format(date);
		}catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
}
